using Dapper;
using MediatR;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ERP.SalesManagement.Return;
using System.Data;

namespace RBAC.Write.Api.Application.Handler.ERP.SalesManagement.Return
{
    /// <summary>
    /// 创建退货通知单处理器
    /// </summary>
    public class CreateReturnNoticeHandler : IRequestHandler<CreateReturnNoticeCommand, APIResult<int>>
    {
        private readonly IDbConnectionFactory _dbConnectionFactory;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbConnectionFactory">数据库连接工厂</param>
        public CreateReturnNoticeHandler(IDbConnectionFactory dbConnectionFactory)
        {
            _dbConnectionFactory = dbConnectionFactory;
        }

        /// <summary>
        /// 处理创建退货通知单请求
        /// </summary>
        /// <param name="request">创建命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>创建结果</returns>
        public async Task<APIResult<int>> Handle(CreateReturnNoticeCommand request, CancellationToken cancellationToken)
        {
            IDbConnection connection = null;
            IDbTransaction transaction = null;

            try
            {
                // 创建数据库连接
                connection = _dbConnectionFactory.CreateConnection();

                // 开始事务
                transaction = connection.BeginTransaction();

                // 1. 自动生成单据编号
                var billCode = await GenerateBillCodeAsync(connection, transaction);

                // 2. 插入退货通知单主表
                var returnNoticeId = await InsertReturnNoticeAsync(connection, transaction, request, billCode);

                // 3. 插入退货物料明细表
                if (request.Items != null && request.Items.Count > 0)
                {
                    await InsertReturnMaterialsAsync(connection, transaction, request.Items, returnNoticeId);
                }

                // 4. 提交事务
                transaction.Commit();

                return new APIResult<int>
                {
                    Code = APIEnums.Success,
                    Msg = "退货通知单创建成功",
                    Data = returnNoticeId
                };
            }
            catch (Exception ex)
            {
                // 回滚事务
                if (transaction != null)
                {
                    try
                    {
                        transaction.Rollback();
                    }
                    catch (Exception rollbackEx)
                    {
                        // 记录回滚异常
                        Console.WriteLine($"事务回滚失败: {rollbackEx.Message}");
                    }
                }

                return new APIResult<int>
                {
                    Code = APIEnums.Fail,
                    Msg = "创建退货通知单失败：" + ex.Message,
                    Data = 0
                };
            }
            finally
            {
                // 确保连接被正确关闭
                if (connection != null && connection.State != ConnectionState.Closed)
                {
                    connection.Close();
                }
            }
        }

        /// <summary>
        /// 自动生成单据编号
        /// </summary>
        /// <param name="connection">数据库连接</param>
        /// <param name="transaction">事务</param>
        /// <returns>单据编号</returns>
        private async Task<string> GenerateBillCodeAsync(IDbConnection connection, IDbTransaction transaction)
        {
            try
            {
                // 查询当前最大单据编号
                var sql = @"
                    SELECT BillCode 
                    FROM ReturnNotice 
                    WHERE BillCode LIKE 'TH%' 
                    AND IsDeleted = 0
                    ORDER BY BillCode DESC 
                    LIMIT 1";

                var lastBillCode = await connection.QueryFirstOrDefaultAsync<string>(sql, null, transaction);

                if (string.IsNullOrEmpty(lastBillCode))
                {
                    // 如果没有记录，从TH000001开始
                    return "TH000001";
                }

                // 提取数字部分并加1
                if (lastBillCode.Length >= 3 && int.TryParse(lastBillCode.Substring(2), out int currentNumber))
                {
                    var nextNumber = currentNumber + 1;
                    return $"TH{nextNumber:D6}";
                }

                // 如果解析失败，返回默认值
                return "TH000001";
            }
            catch
            {
                return "TH000001";
            }
        }

        /// <summary>
        /// 插入退货通知单主表
        /// </summary>
        /// <param name="connection">数据库连接</param>
        /// <param name="transaction">事务</param>
        /// <param name="request">创建请求</param>
        /// <param name="billCode">单据编号</param>
        /// <returns>主表ID</returns>
        private async Task<int> InsertReturnNoticeAsync(
            IDbConnection connection,
            IDbTransaction transaction,
            CreateReturnNoticeCommand request,
            string billCode)
        {
            var sql = @"
                INSERT INTO ReturnNotice (
                    BillCode, BusinessType, Warehouse, Remark, BillDate, 
                    Operator, CustomerName, BillStatus, Reviewer, ReturnReason, 
                    BusinessStatus, ReviewDate, ProcessingMethod, Status, 
                    CreateTime, CreateUser, IsDeleted
                ) VALUES (
                    @BillCode, @BusinessType, @Warehouse, @Remark, @BillDate,
                    @Operator, @CustomerName, @BillStatus, @Reviewer, @ReturnReason,
                    @BusinessStatus, @ReviewDate, @ProcessingMethod, @Status,
                    @CreateTime, @CreateUser, @IsDeleted
                );
                SELECT LAST_INSERT_ID();";

            // 根据状态值映射为中文状态
            string billStatusText = request.Status switch
            {
                0 => "开立",
                1 => "审核",
                2 => "退回",
                _ => "开立" // 默认状态
            };

            var parameters = new
            {
                BillCode = billCode,
                BusinessType = request.BusinessType,
                Warehouse = request.Warehouse,
                Remark = request.Remark,
                BillDate = request.BillDate ?? DateTime.Now,
                Operator = request.Operator ?? "System",
                CustomerName = request.CustomerName,
                BillStatus = billStatusText,
                Reviewer = request.Reviewer,
                ReturnReason = request.ReturnReason,
                BusinessStatus = request.BusinessStatus,
                ReviewDate = request.ReviewDate,
                ProcessingMethod = request.ProcessingMethod,
                Status = request.Status,
                CreateTime = DateTime.Now,
                CreateUser = request.Operator ?? "System",
                IsDeleted = false
            };

            return await connection.QuerySingleAsync<int>(sql, parameters, transaction);
        }

        /// <summary>
        /// 插入退货物料明细表
        /// </summary>
        /// <param name="connection">数据库连接</param>
        /// <param name="transaction">事务</param>
        /// <param name="items">物料明细列表</param>
        /// <param name="returnNoticeId">退货通知单ID</param>
        private async Task InsertReturnMaterialsAsync(
            IDbConnection connection,
            IDbTransaction transaction,
            List<CreateReturnMaterialDto> items,
            int returnNoticeId)
        {
            var sql = @"
                INSERT INTO ReturnMaterials (
                    SalesOrderNumber, ReturnOrderNumber, MaterialCode, MaterialName, 
                    Specification, Unit, Quantity, StockInQuantity, BatchNumber, 
                    Remark, ReturnNoticeId, CreateTime, CreateUser, IsDeleted
                ) VALUES (
                    @SalesOrderNumber, @ReturnOrderNumber, @MaterialCode, @MaterialName,
                    @Specification, @Unit, @Quantity, @StockInQuantity, @BatchNumber,
                    @Remark, @ReturnNoticeId, @CreateTime, @CreateUser, @IsDeleted
                )";

            foreach (var item in items)
            {
                var parameters = new
                {
                    SalesOrderNumber = item.SalesOrderNumber,
                    ReturnOrderNumber = null as string, // 发货单号，初始为空
                    MaterialCode = item.MaterialCode,
                    MaterialName = item.MaterialName,
                    Specification = null as string, // 型号规格，初始为空
                    Unit = item.Unit,
                    Quantity = item.Quantity ?? 0,
                    StockInQuantity = 0, // 入库数量，初始为0
                    BatchNumber = null as string, // 批号，初始为空
                    Remark = item.Remark,
                    ReturnNoticeId = returnNoticeId,
                    CreateTime = DateTime.Now,
                    CreateUser = "System",
                    IsDeleted = false
                };

                await connection.ExecuteAsync(sql, parameters, transaction);
            }
        }
    }
}